/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.mocker.jmock;

import picounit.Interface;
import picounit.SomeException;
import picounit.features.base.DefaultStubFactory;
import picounit.features.base.ProxyFactory;
import picounit.features.base.StubInvocationHandler;
import previous.picounit.Is;
import previous.picounit.Should;
import previous.picounit.Test;
import previous.picounit.Verify;

import java.lang.reflect.InvocationTargetException;

public class StubFactoryTest implements Test {
	private final DefaultStubFactory stubFactory;
	
	private final ProxyFactory mockProxyFactory;

	public StubFactoryTest(ProxyFactory mockProxyFactory) {
		this.stubFactory = new DefaultStubFactory(mockProxyFactory);

		this.mockProxyFactory = mockProxyFactory;
	}

	public void shouldReturnZeroValueForPrimatives(Verify verify) {
		verify.that(stubFactory.create(boolean.class)).isEqualTo(Boolean.FALSE);
		verify.that(stubFactory.create(Boolean.class)).isEqualTo(Boolean.FALSE);
		verify.that(stubFactory.create(byte.class)).isEqualTo(new Byte((byte) 0));
		verify.that(stubFactory.create(Byte.class)).isEqualTo(new Byte((byte) 0));
		verify.that(stubFactory.create(char.class)).isEqualTo(new Character((char) 0));
		verify.that(stubFactory.create(Character.class)).isEqualTo(new Character((char) 0));
		verify.that(stubFactory.create(double.class)).isEqualTo(new Double(0.0));
		verify.that(stubFactory.create(Double.class)).isEqualTo(new Double(0.0));
		verify.that(stubFactory.create(float.class)).isEqualTo(new Float(0.0));
		verify.that(stubFactory.create(Float.class)).isEqualTo(new Float(0.0));
		verify.that(stubFactory.create(int.class)).isEqualTo(new Integer(0));
		verify.that(stubFactory.create(Integer.class)).isEqualTo(new Integer(0));
		verify.that(stubFactory.create(long.class)).isEqualTo(new Long(0));
		verify.that(stubFactory.create(Long.class)).isEqualTo(new Long(0));
		verify.that(stubFactory.create(short.class)).isEqualTo(new Short((short) 0));
		verify.that(stubFactory.create(Short.class)).isEqualTo(new Short((short) 0));
		verify.that(stubFactory.create(Object.class)).isAnInstanceOf(Object.class);
		verify.that(stubFactory.create(String.class)).isEqualTo("");
		verify.that(stubFactory.create(Class.class)).isEqualTo(Class.class);
	}
	
	public void shouldCreateDynamicStubForNonPrimatives(Should should, Verify verify, Is is) {
		Interface interfaceStub = newInterface();

		should.expectTo("Create a dynamic stub")
			.byCalling(mockProxyFactory.create(Interface.class,
				is.instanceOf(StubInvocationHandler.class)))
			.andReturning(interfaceStub);

		should.expectAboveWhenTheFollowingOccurs();

		verify.that(stubFactory.create(Interface.class)).isTheSameAs(interfaceStub);
	}

	private Interface newInterface() {
		return new Interface() {

			public void method() throws SomeException {
			}

			public void awkwardMethod() throws InvocationTargetException {
			}

			public boolean booleanMethod() {
				return false;
			}

			public Object objectMethod() {
				return null;
			}};
	}
}
